/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.analysisModel;

import java.io.Serializable;
import java.util.ArrayList;

import br.ufmg.dees.insane.util.IMatrix;
import br.ufmg.dees.insane.util.IVector;
import br.ufmg.dees.insane.util.geometricProperties.GeometricProperties;

/**
*A class representing a solid analysis model of a ParametricElement.
*@author Lucas, Marcelo & Pitangueira, Roque & Fonseca, Flavio
*@version 1.0
*@since September 2004, modified October 2006
*/
public class Solid implements AnalysisModel, Serializable {

	private static final long serialVersionUID = 1L;
	
	/** Constructs a Solid analysis model*/
	public Solid()
	{
	}
	
	/* (non-Javadoc)
     * @see br.ufmg.dees.insane.analysisModel.AnalysisModel#getLabel()
     */
	public String getLabel() {
		return "Solid";
	}
	
	/* (non-Javadoc)
     * @see br.ufmg.dees.insane.analysisModel.AnalysisModel#getInternalVariableOperator(br.ufmg.dees.insane.util.IMatrix, br.ufmg.dees.insane.util.IVector, br.ufmg.dees.insane.util.IMatrix)
     */
    public IMatrix getInternalVariableOperator(IMatrix d, IMatrix d2, IVector n, IMatrix c) {
    	int nNos = d.getNumCol();
		IMatrix invertJacobian;
		IMatrix dG = new IMatrix(3,d.getNumCol());
		IMatrix b = new IMatrix(6,(3*nNos));
		dG.setZero();
		b.setZero();
		
		invertJacobian = this.invertJacobian(this.getJacobian(d, c));
		dG.mul(invertJacobian, d);
		
		for(int i = 0; i < nNos; i++) 
		{
			b.setElement(0,(3*i),dG.getElement(0,i));
			b.setElement(1,((3*i)+1),dG.getElement(1,i));
			b.setElement(2,((3*i)+2),dG.getElement(2,i));
			b.setElement(3,(3*i),dG.getElement(1,i));
			b.setElement(3,((3*i)+1),dG.getElement(0,i));
			b.setElement(4,((3*i)+1),dG.getElement(2,i));
			b.setElement(4,((3*i)+2),dG.getElement(1,i));
			b.setElement(5,(3*i),dG.getElement(2,i));
			b.setElement(5,((3*i)+2),dG.getElement(0,i));
		}
			return(b);
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.analysisModel.AnalysisModel#getDualInternalVariableOperator(br.ufmg.dees.insane.util.IMatrix)
     */
    public IMatrix getDualInternalVariableOperator(IMatrix e) {
IMatrix d = new IMatrix(6,6);
		
		double elast = e.getElement(0,0);
		double ni = e.getElement(2,0);
		double k = ((elast)/((1+ni)*(1-(2*ni))));
		
		d.setElement(0,0, ((1*k)*(1-ni)));
		d.setElement(0,1, (ni*k));
		d.setElement(0,2, (ni*k));
		d.setElement(0,3, 0);
		d.setElement(0,4, 0);
		d.setElement(0,5, 0);
		d.setElement(1,0, (ni*k));
		d.setElement(1,1, ((1*k)*(1-ni)));
		d.setElement(1,2, (ni*k));
		d.setElement(1,3, 0);
		d.setElement(1,4, 0);
		d.setElement(1,5, 0);
		d.setElement(2,0, (ni*k));
		d.setElement(2,1, (ni*k));
		d.setElement(2,2, ((1*k)*(1-ni)));
		d.setElement(2,3, 0);
		d.setElement(2,4, 0);
		d.setElement(2,5, 0);
		d.setElement(3,0, 0);
		d.setElement(3,1, 0);
		d.setElement(3,2, 0);
		d.setElement(3,3, (0.5*(1-(2*ni))));
		d.setElement(3,4, 0);
		d.setElement(3,5, 0);
		d.setElement(4,0, 0);
		d.setElement(4,1, 0);
		d.setElement(4,2, 0);
		d.setElement(4,3, 0);
		d.setElement(4,4, (0.5*(1-(2*ni))));
		d.setElement(4,5, 0);
		d.setElement(5,0, 0);
		d.setElement(5,1, 0);
		d.setElement(5,2, 0);
		d.setElement(5,3, 0);
		d.setElement(5,4, 0);
		d.setElement(5,5, (0.5*(1-(2*ni))));
		
		return(d);
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.analysisModel.AnalysisModel#getStateVariableOperator(br.ufmg.dees.insane.util.IVector)
     */
    public IMatrix getStateVariableOperator(IMatrix d, IVector n, IMatrix c) {
    	IMatrix matrixN = new IMatrix(3,(3*(n.getSize())));
		matrixN.setZero();
		
		for(int i = 0; i < (n.getSize()); i++)
		{
			for(int j = 0; j < 3; j++)
			{
				matrixN.setElement( j, (3*i)+j, (n.getElement(i)));
			}
		}
			return matrixN;
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.analysisModel.AnalysisModel#getNumberOfDualInternalVariables()
     */
    public int getNumberOfDualInternalVariables()
	{
		return 6;
	}

    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.analysisModel.AnalysisModel#getNumberOfInternalVariables()
     */
    public int getNumberOfInternalVariables()
	{
		return 6;
	}
	
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.analysisModel.AnalysisModel#getDualInternalVariablesDirLabels()
     */
    public String[] getDualInternalVariablesLabels() {
        String[] Dlabels = {"sigmaXX", "sigmaYY", "sigmaZZ", "tauXY", "tauYZ", "tauZX"};
        return Dlabels;
    }
    
    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.analysisModel.AnalysisModel#getInternalVariablesDirLabels()
     */
    public String[] getInternalVariablesLabels() {
        String[] Dlabels = {"epsilonXX", "epsilonYY", "epsilonZZ", "gammaXY", "gammaYZ", "gammaZX"};
        return Dlabels;
    }
    
	/* (non-Javadoc)
     * @see br.ufmg.dees.insane.analysisModel.AnalysisModel#getJacobianTransformation(br.ufmg.dees.insane.util.IMatrix, br.ufmg.dees.insane.util.IMatrix)
     */
	public double getJacobianTransformation(IMatrix dl, IMatrix cN)
	{
		IMatrix jacobian = new IMatrix(this.getDominion(),this.getDominion());
		jacobian.setZero();
		jacobian.mul(dl, cN);
		
		return(jacobian.determinantLU());
	}
	
	/** Return the jacobian matrix.
	*@param dl The matrix of local derivates.
	*@param cN The matrix of nodal coordinates.
	*@return dl * cN The jacobian matrix.
	*/
	public IMatrix getJacobian(IMatrix dl, IMatrix cN)
	{
		IMatrix jacobian = new IMatrix(this.getDominion(),this.getDominion());
		jacobian.setZero();
		jacobian.mul(dl, cN);
		
		return(jacobian);
	}
	
	/** Return the inverse of jacobian matrix.
	*@param a The jacobian matrix.
	*@return the inverse of jacobian matrix.
	*/
	protected IMatrix invertJacobian(IMatrix a)
	{
		IMatrix b = new IMatrix(3,3);
		b.setZero();
		
		b.setElement(0,0, (((a.getElement(1,1))*(a.getElement(2,2)))-((a.getElement(1,2))*(a.getElement(2,1)))));
		b.setElement(0,1, (-1)*(((a.getElement(1,0))*(a.getElement(2,2)))-((a.getElement(1,2))*(a.getElement(2,0)))));
		b.setElement(0,2, (((a.getElement(1,0))*(a.getElement(2,1)))-((a.getElement(1,1))*(a.getElement(2,0)))));
		b.setElement(1,0, (-1)*(((a.getElement(0,1))*(a.getElement(2,2)))-((a.getElement(0,2))*(a.getElement(2,1)))));
		b.setElement(1,1, (((a.getElement(0,0))*(a.getElement(2,2)))-((a.getElement(0,2))*(a.getElement(2,0)))));
		b.setElement(1,2, (-1)*(((a.getElement(0,0))*(a.getElement(2,1)))-((a.getElement(0,1))*(a.getElement(2,0)))));
		b.setElement(2,0, (((a.getElement(0,1))*(a.getElement(1,2)))-((a.getElement(0,2))*(a.getElement(1,1)))));
		b.setElement(2,1, (-1)*(((a.getElement(0,0))*(a.getElement(1,2)))-((a.getElement(0,2))*(a.getElement(1,0)))));
		b.setElement(2,2, (((a.getElement(0,0))*(a.getElement(1,1)))-((a.getElement(0,1))*(a.getElement(1,0)))));
		
		b.transpose();
		b.setScale((1/(a.determinantLU())));
		
		return b;
	}
	
	public IMatrix getInternalVariableOperator(IMatrix d, IMatrix d2, IVector n, IMatrix c, IMatrix u) {
		// TODO Auto-generated method stub
		return null;
	}

	public IMatrix modifyInternalVariableOperator(IMatrix e, IMatrix p) {
		// TODO Auto-generated method stub
		return null;
	}

	public IMatrix modifyDualInternalVariableOperator(IMatrix e, GeometricProperties gps) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public IVector modifyDualInternalVariableVector(IVector s, GeometricProperties gps) {
		// TODO Auto-generated method stub
		return null;
	}

	public IMatrix getGeometricOperator(IVector n1) {
		// TODO Auto-generated method stub
		return null;
	}

	public IMatrix getInternalVariablesTensor(IVector a, IMatrix b) {
		// TODO Auto-generated method stub
		return null;
	}

	public IMatrix getDualInternalVariablesTensor(IVector a, IMatrix b) {
		// TODO Auto-generated method stub
		return null;
	}

	public IVector expandVector(IVector a) {
		// TODO Auto-generated method stub
		return null;
	}

	public IMatrix expandTensor(IVector a) {
		// TODO Auto-generated method stub
		return null;
	}

	public IVector reduceVector(IVector a) {
		// TODO Auto-generated method stub
		return null;
	}

	public IVector reduceTensor(IMatrix a) {
		// TODO Auto-generated method stub
		return null;
	}

	public int getDominion() {
		// TODO Auto-generated method stub
		return 0;
	}

	public double getIntegrationFactor(IVector n, IMatrix cN, GeometricProperties gps) {
		// TODO Auto-generated method stub
		return 1.0;
	}

	public IMatrix getTransformationMatrix(IMatrix dl, IMatrix cN) {
		// TODO Auto-generated method stub
		return null;
	}

	public double getJ2(IVector s) {
		// TODO Auto-generated method stub
		return 0;
	}

	public IVector getdJ2dSIG(IVector s) {
		// TODO Auto-generated method stub
		return null;
	}

	public double getJ3(IVector s) {
		// TODO Auto-generated method stub
		return 0;
	}

	public IVector getdJ3dSIG(IVector s) {
		// TODO Auto-generated method stub
		return null;
	}

	public double getI1(IVector s) {
		// TODO Auto-generated method stub
		return 0;
	}

	public IVector getdI1dSIG(IVector s) {
		// TODO Auto-generated method stub
		return null;
	}

	public double getI2(IVector s) {
		// TODO Auto-generated method stub
		return 0;
	}

	public IVector getdI2dSIG(IVector s) {
		// TODO Auto-generated method stub
		return null;
	}

	public double getI3(IVector s) {
		// TODO Auto-generated method stub
		return 0;
	}

	public IVector getdI3dSIG(IVector s) {
		// TODO Auto-generated method stub
		return null;
	}

	public ArrayList getDOFLabels(int n) {
		// TODO Auto-generated method stub
		return null;
	}

	public ArrayList getDOFLabels() {
		// TODO Auto-generated method stub
		return null;
	}

	public IMatrix getPMatrix() {
		// TODO Auto-generated method stub
		return null;
	}

}